<?php
/*
 *  Maniter: A webbased business managment tool.
 *  Copyright (C) 2007  Dimitri Michaux <dimitri.michaux@gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * purchaselist.class.php, Maniter
 * 
 * The base class for purchaseorders and offers.
 *
 * @author Dimitri Michaux
 * @version 0.1
 * @package maniter_classes
 */

require_once( 'purchase.class.php' );
require_once( _PATH_TO_JIBA.'contactinfo.class.php' );
require_once( _PATH_TO_JIBA.'dbobject.class.php' );
require_once( _PATH_TO_JIBA.'timestamp.class.php' );

abstract class PurchaseList extends DBObject {
  /**
    * Array with all the available purchases
    *
    * @var Purchase
    */
  protected $_purchases;
  
  /**
    * Amount of purchases
    *
    * @var int
    */
  protected $_count;
  
  /**
    * Information of the client
    *
    * @var ContactInfo
    */
  protected $_clientInfo;
  
  /**
    * Printed flag
    *
    * @var bool
    */
  protected $_printed;
  
  
  /**
    * Finished flag
    *
    * @var bool
    */
  protected $_finished;
  
  /**
    * Used for displaying
    *
    * @var int
    */
  protected $_dispId;
	
  /**
    * Returns the owner info
    *
    * @return ContactInfo
    */
  public static function getOwnerInfo(){
    $info = unserialize( DB::get()->getItem( 'var_blob', 'value', "name='ownerinfo'" ) );
    
    if( $info == "" )
      return new ContactInfo;
    else
      return (object)$info;
  }
  
  public static function saveOwnerInfo( &$info ){
    $db = DB::get();
  
    $data = array( 'name'  => 'ownerinfo',
                   'value' => serialize($info) );
    
    $db->update( 'var_blob', $data, "name='ownerinfo'" );
  }
  
  protected static function &_getClientInfo( &$file ){
    $res = DB::get()->getRows( 'contact_info', "parent='{$file->getId()}'", null, true, 1 );
    
    $file->getClientInfo()->setBankAccount( $res[0]['bankaccount'] );
    $file->getClientInfo()->setCity( $res[0]['city'] );
    $file->getClientInfo()->setCompany( $res[0]['company'] );
    $file->getClientInfo()->setEmail( $res[0]['email'] );
    $file->getClientInfo()->setFax( $res[0]['fax'] );
    $file->getClientInfo()->setName( $res[0]['name'] );
    $file->getClientInfo()->setPhone( $$res[0]['phone'] );
    $file->getClientInfo()->setStreet( $res[0]['street'] );
    $file->getClientInfo()->setVatNr( $res[0]['vatnr'] );
    $file->getClientInfo()->setWebsite( $$res[0]['website'] );
    
    return $file;
  }
    
  protected static function &_getPurchases( &$file ){
    $res = DB::get()->getRows( 'purchases', "parent='{$file->getId()}'", 'id', true, null );
    
    $num = count( $res );
    
    for( $i=0 ; $i<$num ; $i++ ){
      $nr = $file->newPurchase($res[$i]['id']);
  
      $file->getPurchase($nr)->setAmount($res[$i]['amount']);
      $file->getPurchase($nr)->setDescription($res[$i]['description']);
      $file->getPurchase($nr)->setPrice($res[$i]['price']);
      $file->getPurchase($nr)->setVat($res[$i]['vat']);
      $file->getPurchase($nr)->setPos($i);
    }
    
    return $file;
  }
	
  /**
    * Constructor: initializes variables and objects
    * + creates a database entry for this purchaseorder.
    */
  protected function __construct() {
    parent::__construct();
    
    $this->_id = $this->_createId();
    
    $this->_clientInfo = new ContactInfo();
    $this->_createDate = date( "Y-m-d H:i:s" );	//mysql timestamp

    $this->_finished = false;
    $this->_printed = false;
    $this->_count = 0;
    $this->_purchases = array();
  }
	
	/**
	 * Cleans up the _purchases array before serialization
	 *
	 * @return string
	 */
	public function __sleep() {
		//cleanup purchases array
		$newArray = array();
		$oldArray = $this->_purchases;
		
		foreach( $oldArray as &$item )
			$newArray[] = $item;
			
		$this->_purchases = $newArray;
		$this->_count = count( $this->_purchases );
		
		//variables to save
		return array('_id', '_purchases', '_count', '_clientInfo', '_printed', '_finished',
						'_createDate' );
	}
	
	/**
	 * This function is only here to compatability with older versions
	 * that don't have the _footerText variable.
	 * 
	 */
	abstract public function __wakeup();
	
	/**
	 * Sets the finished flag to true
	 *
	 */
	public function setFinished() {
		$this->_finished = true;
	}
	
	/**
	 * Sets the finished flag to false
	 *
	 */
	public function unSetFinished() {
		$this->_finished = false;
	}
	
	public function finished(){
		return $this->_finished;
	}
	
	public function printed(){
		return $this->_printed;
	}
	
	public function setPrinted(){
	 	$this->_printed = true;
	}
	
	/**
	 * Returns the printable id of the order
	 *
	 * @return int
	 */
	public function getDispId(){
		return $this->_dispId;
	}
	
	public function setDispId( $id ){
		$this->_dispId = $id;
	}
	
	/**
	 * Returns the day the payment is due
	 *
	 * @return string
	 */
	public function getDueDate() {
		$create = strtotime( $this->_createDate );
		$due = strtotime( "+14 days", $create );
		
		return date( "d-m-Y", $due );
	}
	
	/**
	 * Add a new purchase item to the list
	 *
	 * @return int	id of the item
	 */
	public function newPurchase($dbId=-1) {
		$this->_purchases[ $this->_count  ] = new Purchase($dbId);
		return $this->_count++;
	}
	
	/**
	 * Returns a purchase
	 *
	 * @param int $id
	 * @return Purchase
	 */
	public function &getPurchase( $id ) {
		return $this->_purchases[$id];
	}
	
	/**
	 * Return the clients info
	 *
	 * @return ContactInfo
	 */
	public function &getClientInfo() {
		return $this->_clientInfo;
	}
	
	/**
	 * Returns the amount of puchases
	 *
	 * @return int
	 */
	public function purchases() {
		return $this->_count;
	}
	
	/**
	 * Remove a purchase by id
	 *
	 * @param int $id
	 * @return bool	true if ok
	 */
	public function removePurchase( $id ) {
		if( array_key_exists($id,$this->_purchases) ) {
			DB::get()->delete( 'purchases', 'id', $this->_purchases[$id]->getDbId() );
			unset( $this->_purchases[$id] );
			
			//cleanup purchases array
			$newArray = array();
			$oldArray = $this->_purchases;
			
			$i=0;
			foreach( $oldArray as &$item )
				$newArray[] = $item->setPos($i++);
				
			$this->_purchases = $newArray;
			$this->_count = count( $this->_purchases );
			
			return true;
		} else
			return false;
	}
	
	/**
	 * Returns the total cost (vat included)
	 *
	 * @return float
	 */
	public function getTotal() {
		$total = 0;
	
		foreach( $this->_purchases as &$purchase )
			$total += $purchase->getTotal();
		
		return round($total, 2);
	}
	
  /**
    * Returns the subtotal (vat not included)
    *
    * @return float
    */
  public function getSubtotal() {
    $total = 0;
  
    foreach( $this->_purchases as &$purchase )
      $total += $purchase->getSubtotal();
    
    return round($total, 2);
  }
	
  /**
    * Returns the subtotal in a human readable format
    *
    * @return string
    */
  public function printSubtotal() {
    return number_format($this->getSubtotal(), 2, ',', ' ');
  }
  
  /**
    * Returns the total in a human readable format
    *
    * @return string
    */
  public function printTotal() {
    return number_format($this->getTotal(), 2, ',', ' ');
  }
	
  /**
    * Returns an array with the total vat for every different vat%
    *
    * @param bool $print
    * @return array	array('vat%'=>'total')
    */
  public function getVatPerVat() {
    $result = array();
          
    foreach( $this->_purchases as $purchase ) {
      if( !isset($result[$purchase->printVat()]) ){
        $result[$purchase->printVat()] = 0;
      }
    
      $result[$purchase->printVat()] += $purchase->getTotalVat();
    }
    ksort( $result );
    
    foreach( $result as &$value ){
      $value = number_format($value, 2, ',', ' ');
    }
    
    //delete the empty key
    if( isset($result[""]) )
      unset( $result[""] );
    
    return $result;
  }
	
  /**
  * Deletes this purchase list
  *
  */
  //abstract function remove();
	
  /**
    * Saves the current purchase list
    * (purchases and contactinfo)
    *
    * @param  PurchaseList
    * @return bool
    */
  public static function save( $list ) {
    foreach( $list->_purchases as &$purchase )
      $purchase->save( $list->_id );

    //save contact info
    $data = array(  'parent'      => $list->_id,
                    'company'     => $list->_clientInfo->getCompany(),
                    'name'        => $list->_clientInfo->getName(),
                    'street'      => $list->_clientInfo->getStreet(),
                    'city'        => $list->_clientInfo->getCity(),
                    'phone'       => $list->_clientInfo->getPhone(),
                    'fax'         => $list->_clientInfo->getFax(),
                    'vatnr'       => $list->_clientInfo->getVatNr(),
                    'bankaccount' => $list->_clientInfo->getBankAccount(),
                    'email'       => $list->_clientInfo->getEmail(),
                    'website'     => $list->_clientInfo->getWebsite() );

    DB::get()->save( 'contact_info', $data, true );
  }
}
?>